import { Component, OnInit } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';

import { Hero } from '../hero';
import { HeroService } from '../hero.service';

@Component({
  selector: 'app-hero-search',
  templateUrl: './hero-search.component.html',
  styleUrls: ['./hero-search.component.css'],
})
export class HeroSearchComponent implements OnInit {
  constructor(private heroService: HeroService) {}

  ngOnInit(): void {
    this.heroes$ = this.searchTerms.pipe(
      // wait 300ms after each keystroke before considering the term  // 相当于在一定时间内连续收到next()值，只保留最后一个
      debounceTime(300),

      // ignore new term if same as previous term  //  会确保只在过滤条件变化时才发送请求，大概是本次next()值与上一次next()不一样时才通过
      distinctUntilChanged(),

      // switch to new search observable each time the term changes  //  它会取消并丢弃以前的搜索可观察对象，只保留最近的，大概就是丢弃未完成的流
      switchMap((term: string) => this.heroService.searchHeroes(term))
      //取消前一个 searchHeroes() 可观察对象并不会中止尚未完成的 HTTP 请求。那些不想要的结果只会在它们抵达应用代码之前被舍弃
    );
  }

  // Push a search term into the observable stream.
  search(term: string): void {
    this.searchTerms.next(term);
  }

  heroes$!: Observable<Hero[]>; //  Observable是单播的, 每个订阅的Observer都拥有Observable的独立执行
  private searchTerms = new Subject<string>(); //  类似于广播队列流，订阅后才能等到next()压入的对象,Subject类似于Observable，但可以多播到许多观察者
}
